iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 23
1
AI & Data

30 天學會深度學習和 Tensorflow系列 第 23

22. 深度學習甜點系列:語言生成模型

  • 分享至 

  • xImage
  •  

Sequence generation model

和影像生成不同的是,序列型資料因為有時序的連續性,所以使用 GAN 的方法來生成序列是較少見的。但和影像生成相似的是,序列型資料的生成模型,也需要對訓練資料分佈做估算,並從估算的訓練資料分佈來生成序列。

在前幾篇貼文,可以看到許多關於學習 word embedding 的模型,利用預測序列中下一個位置的方法來做訓練。這種預測方法,便是利用序列生成的方式估算序列間相依關係的機率,並學習該訓練集中隱含的語義群聚(在 RNN 中屬於狀態序列),而使 word embedding 能夠維持語義間的相似性。

我們已看過使用 Feed Forward Network 的方法來建立 Neural Language Model,並可由此模型來產生符合英文語意序列。現在,我們來看看一個 RNN 架構的序列生成模型是如何產生符合訓練資料分布的句子。

在架構上,序列生成模型是屬於 one-to-many 的架構,one 指的是,此 RNN 架構只取一個輸入,而 many 則是架構會有多個輸出,直到生成句子結尾字詞,通常以<EOS>標註。我們可以以 “Cats average 15 hours of sleep a day.” 這個訓練例句和下面的投影片截圖來說明序列生成模型的訓練流程。

RNN sequence generation model

和一般 RNN 架構相同的是,我們需要一個初始狀態輸出,a<0>,通常會初始化為都為零的向量,而在 RNN 第一個狀態除了接受初始狀態外,還有訓練句子的第一個位置輸入,亦即 x<1>,或Cats這個字,這是這個語言生成架構中唯一一個由外部接受的輸入,其餘的輸入都會由語言模型自行生成。

在訓練階段,RNN 序列中的每一個狀態需要估算該位置的輸出機率分佈,也就是y_hat_t 。這個輸出分佈是一個長度為字彙集的大小,|V|,的輸出向量,並透過 softmax 函式來學習。而在下一個 RNN 狀態中,輸入將會使用前一狀態的輸出,而不會使用真正序列的輸入。

那麼真正的輸入呢?一個訓練良好的語言模型,該位置的輸出應當等同於下一個位置的輸入。所以序列生成模型會將下一個位置的輸入當作真實目的標籤,並且透過損失函式,通常為 cross-entropy 量測 Loss function 生成字彙和此位置的真正字彙之間的差異。

上圖中用第三個時步來說明以上所述的觀念。首先在第二個狀態的輸出,y_hat_2 應當要生成
x<3>,15 此字,但我們不會用 x<3> 做輸入,而是用 y_hat_2。所以 x<3> 會成為訓練的真正標示 y<2>,也就是即綠色箭頭所指的部分。而紅色箭頭則是利用 y_hat_2 和 y<2> 計算 cross-entropy 損失。

下圖可以看到以以字母為基礎的語言生成模型,主要的差別在於字彙集的不同。另外還有一個不同點則是單詞為基礎的語言生成模型需要處理<UNK> token,或在取樣的過程中遭遇 OOV 的情況。

sampling sequence

在生成模型中,有兩種可能的方法來處理生成<UNK> token,一是持續拒絕產生<UNK>的取樣結果,直到產生有意義的單詞,另外一個則是接受<UNK> token。哪一個方法較好,端看語言生成的應用。

在隨意序列生成中,每一個位置經過取樣的輸出,取樣方法會決定生成的序列是否非常接近原輸入。若採取 uniform 取樣,則生成的序列就會接近胡言亂語的狀態,而若對高機率,或輸出分佈的峰值取樣則會生成和訓練資料相近的序列。

最後關於語言生成模型,有一點要注意的,隨意序列生成和生成符合訓練語言模型最大機率的序列是相當不相同。前者需要根據每一位置的輸出分佈做隨意取樣(random sampling),而後者則需要找出擁有最大條件機率的序列來生成,通常被稱為語言模型的 inference 階段。

前者的隨意取樣會保證每一次生成的序列不盡相同,但會符合輸出分佈,後者則會保證根據模型分佈,而輸出最大可能的序列,但因為語言生成的搜尋空間相當龐大(等同於字彙量),所以經常使用 greedy 的演算法(deterministic search)來找尋具有最大可能的序列生成,而輸出通常為一固定。我們會在下一篇中,提到如何生成最大可能序列。

Sequence to Sequence Model Architecture

另外一個架構與序列生成有關的則是 sequence to sequence 架構,往後將簡稱此架構為 Seq2Seq。這個架構用一個序列當作輸出,並轉換成另外一個相關的序列。Seq2Seq 架構中包含了一個 encoder 負責對來源輸入編碼的功能,而一個 decoder 則負責生成目標輸出。模型則是使用 ”Un-rolled” 的方式,先用編碼器(encoder)讀入輸入來源序列,再透過一個如解碼器的架構來輸出目標序列。

Seq2Seq 的架構上是屬於 many-to-many 的形式,而其架構的粗略圖示,可以由下面的課程投影片圖解 “Un-rolled” 的 Seq2Seq 架構:
seq2seq

Seq2Seq 又可因為 encoder 和 decoder 的實踐介面不同,而有兩種主要的類別,分別是 LSTM-transducerLSTM-autoencoder。前者多用於語言模型,如在兩個語言間的機械翻譯和問答式的對話機器人。

LSTM auto-encoder,其目的就是將視為被編碼的來源序列,輸出成解碼後的目標序列。訓練編碼到解碼的對應的函式可利用無監督學習或重建的方式。透過對 auto-encoder 的損失函式,亦為一個重建損失量度值,使用最佳化演算法來達到編碼的最小重建損失。

LSTM-transducer 則是屬於系統生成的模型,通常會將餵入 encoder 的輸入序列,並將 encoder 最後一個狀態當作 decoder 的初始狀態繼續生成輸出序列。我們以機械翻譯來做解釋。輸入序列可以是來源語言的訓練句子,而輸出序列則是目標語言的訓練句子。這兩種語言雖然各自擁有同ㄧ個字彙集,但因為共享同一個語義,在 Google 發表的 Seq2Seq NMT paper 中,稱呼為 thought vector 。此 thought vector 是 encoder 最後的一個 RNN 狀態,基於兩個語言中相通或共享的語義,並會直接成為 decoder 的初始狀態,加以生成目標語言序列。

Deep RNN

在實際訓練一個機械翻譯模型中,有許多不同的細節來調整 Seq2Seq,包括了考慮是否對來源語言和目標語言使用相同或相異的 word embedding。但同時,為了能模擬序列在特徵空間中高階的表示,而非只是捕捉序列間的相依關係,此時我們可以在時序位置上,垂直堆疊數個 hidden layers,就如在序列中的每一個位置建立一個小型的 Feed Forward network 一般。然而,很不幸地,由於 RNN 在時序方向已是一個深度的類神經網路,所以在捕捉特徵向量的方向,通常疊個三層,其計算量就非常大了。

一個 Deep RNN 的架構可見下圖投影片截圖:

Multilayer RNN

另外一個方法去解決無法在垂直或語義特徵方向堆疊深度 fully-connected layers,則是放棄橫向或時序方向的連結,而只是堆高而已。最後,在往後的貼文中,我們將會透過機械翻譯的例子來更仔細的解構 Seq2Seq 模型。


上一篇
21. 深度學習甜點系列:以字母為基礎的語言模型
下一篇
23. 深度學習甜點系列:機械翻譯員如何翻譯
系列文
30 天學會深度學習和 Tensorflow30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言